package com.example.artemis.statistics;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 统计数据仓库
 * 负责统计数据的存储和管理
 */
public class StatisticsRepository {

    // 全局统计
    private final MessageStatistics globalStatistics;

    // 队列统计映射
    private final Map<String, QueueStatistics> queueStatisticsMap;

    // 时间窗口统计列表（线程安全的ConcurrentHashMap）
    private final Map<String, TimeWindowStatistics> timeWindowMap;

    public StatisticsRepository() {
        this.globalStatistics = new MessageStatistics();
        this.queueStatisticsMap = new ConcurrentHashMap<>();
        this.timeWindowMap = new ConcurrentHashMap<>();
    }

    // ================== 全局统计 ==================

    /**
     * 获取全局统计
     */
    public MessageStatistics getGlobalStatistics() {
        return globalStatistics;
    }

    // ================== 队列统计 ==================

    /**
     * 获取队列统计
     */
    public QueueStatistics getQueueStatistics(String queueName) {
        return queueStatisticsMap.get(queueName);
    }

    /**
     * 获取或创建队列统计
     */
    public QueueStatistics getOrCreateQueueStatistics(String queueName) {
        return queueStatisticsMap.computeIfAbsent(queueName, QueueStatistics::new);
    }

    /**
     * 获取所有队列统计
     */
    public Map<String, QueueStatistics> getAllQueueStatistics() {
        return new ConcurrentHashMap<>(queueStatisticsMap);
    }

    /**
     * 移除队列统计
     */
    public QueueStatistics removeQueueStatistics(String queueName) {
        return queueStatisticsMap.remove(queueName);
    }

    /**
     * 清空所有队列统计
     */
    public void clearQueueStatistics() {
        queueStatisticsMap.clear();
    }

    // ================== 时间窗口统计 ==================

    /**
     * 获取时间窗口统计
     */
    public TimeWindowStatistics getTimeWindowStatistics(String windowKey) {
        return timeWindowMap.get(windowKey);
    }

    /**
     * 获取或创建时间窗口统计
     */
    public TimeWindowStatistics getOrCreateTimeWindowStatistics(String windowKey, LocalDateTime windowStart, long windowSizeMinutes) {
        return timeWindowMap.computeIfAbsent(windowKey,
                k -> new TimeWindowStatistics(windowStart, windowSizeMinutes));
    }

    /**
     * 添加时间窗口统计
     */
    public void addTimeWindowStatistics(String windowKey, TimeWindowStatistics statistics) {
        timeWindowMap.put(windowKey, statistics);
    }

    /**
     * 移除时间窗口统计
     */
    public TimeWindowStatistics removeTimeWindowStatistics(String windowKey) {
        return timeWindowMap.remove(windowKey);
    }

    /**
     * 清空所有时间窗口统计
     */
    public void clearTimeWindowStatistics() {
        timeWindowMap.clear();
    }

    /**
     * 清理过期的时间窗口统计
     */
    public void cleanupExpiredTimeWindows() {
        timeWindowMap.entrySet().removeIf(entry -> entry.getValue().isExpired());
    }

    /**
     * 获取所有时间窗口统计
     */
    public Map<String, TimeWindowStatistics> getAllTimeWindowStatistics() {
        return new ConcurrentHashMap<>(timeWindowMap);
    }

    // ================== 批量操作 ==================

    /**
     * 重置所有统计数据
     */
    public void resetAll() {
        globalStatistics.reset();
        queueStatisticsMap.values().forEach(QueueStatistics::reset);
        timeWindowMap.clear();
    }

    /**
     * 获取统计摘要
     */
    public String getSummary() {
        StringBuilder summary = new StringBuilder();
        summary.append("统计数据仓库摘要:\n");
        summary.append(String.format("  全局统计: %s\n", globalStatistics.toString()));
        summary.append(String.format("  队列统计数量: %d\n", queueStatisticsMap.size()));
        summary.append(String.format("  时间窗口统计数量: %d\n", timeWindowMap.size()));
        return summary.toString();
    }

    // ================== 工具方法 ==================

    /**
     * 生成时间窗口键
     */
    public static String generateTimeWindowKey(LocalDateTime windowStart, long windowSizeMinutes) {
        return String.format("%s_%dmin", windowStart.toString(), windowSizeMinutes);
    }

    /**
     * 生成队列键
     */
    public static String generateQueueKey(String queueName) {
        return queueName;
    }
}